package com.erp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.erp.common.BaseContext;
import com.erp.common.CustomException;
import com.erp.common.R;
import com.erp.common.SuperConstant;
import com.erp.dao.PayableDao;
import com.erp.entity.FinancialJournal;
import com.erp.entity.GeneralLedger;
import com.erp.entity.Payable;
import com.erp.service.FinancialJournalService;
import com.erp.service.GeneralLedgerService;
import com.erp.service.PayableService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class PayableServiceImpl extends ServiceImpl<PayableDao, Payable> implements PayableService {

    @Autowired
    private GeneralLedgerService generalLedgerService;

    @Autowired
    private FinancialJournalService financialJournalService;

    /**
     * 保存应付账信息 并更新总账表对应信息 最后记录日志
     *
     * @param payable
     * @return
     */
    @Override
    @Transactional
    public R<String> savePayableAndLedger(Payable payable) {

        //设置默认字段
        payable.setStatus(0);
        if (Objects.isNull(payable.getCreateDateTime())) {
            payable.setCreateDateTime(LocalDateTime.now());
        }

        //对应付账表添加数据
        this.save(payable);

        //记录日志
        FinancialJournal financialJournal = new FinancialJournal
                (BaseContext.getCurrentId(), SuperConstant.PayableTable, SuperConstant.Save);
        financialJournalService.save(financialJournal);

        //条件构造器 查找generalLedger中是否有type为应收账的数据
        LambdaQueryWrapper<GeneralLedger> ledgerLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ledgerLambdaQueryWrapper.eq(GeneralLedger::getType, "应付账");
        List<GeneralLedger> list = generalLedgerService.list(ledgerLambdaQueryWrapper);

        //如果没有 则创建对象并设置默认值最后保存进数据库
        if (list.size() == 0) {
            log.info("新增总账");
            GeneralLedger generalLedger = new GeneralLedger();
            generalLedger.setMoney(payable.getMoney());
            generalLedger.setType("应付账");
            generalLedgerService.save(generalLedger);
        } else if (list.size() == 1) {
            log.info("更新总账");
            //如果有 则取出该对象 对number字段进行修改后更新到数据库
            GeneralLedger generalLedger = list.get(0);
            generalLedger.setMoney(generalLedger.getMoney() + payable.getMoney());
            generalLedgerService.updateById(generalLedger);
        } else {
            throw new CustomException("总账表异常，通知管理员维护");
        }

        return R.success("添加成功");
    }

    /**
     * 根据id删除应付账信息 并更新总账表对应信息 最后记录日志
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public R<String> deleteByIdAndUpdateLedger(Long id) {
        //判断id是否存在
        Payable payable = this.getById(id);
        if (ObjectUtils.isEmpty(payable)) {
            return R.error("id不存在");
        }

        //条件构造器
        LambdaQueryWrapper<GeneralLedger> ledgerLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ledgerLambdaQueryWrapper.eq(GeneralLedger::getType, "应付账");
        List<GeneralLedger> list = generalLedgerService.list(ledgerLambdaQueryWrapper);

        //判断总账分类是否存在
        if (list.size() == 0) {
            return R.error("删除异常,应付账分类不存在");
        } else if (list.size() > 1) {
            throw new CustomException("总账表异常，通知管理员维护");
        }

        //判断总账分类金额是否正常
        Long number = payable.getMoney();
        GeneralLedger generalLedger = list.get(0);

        //更新总账数据

        generalLedger.setMoney(generalLedger.getMoney() - number);
        generalLedgerService.updateById(generalLedger);

        //删除应付账数据
        this.removeById(id);

        //记录日志
        FinancialJournal financialJournal = new FinancialJournal
                (BaseContext.getCurrentId(), SuperConstant.PayableTable, SuperConstant.Delete, id.toString());
        financialJournalService.save(financialJournal);

        return R.success("删除成功");
    }

    /**
     * 更新应付账信息 并更新总账表对应信息 最后记录日志
     *
     * @param payable
     * @return
     */
    @Override
    @Transactional
    public R<String> updateByIdAndUpdateLedger(Payable payable) {

        GeneralLedger generalLedger = generalLedgerService.getById(payable.getLedgerId());

        Long newMoney = payable.getMoney();

        //判断是否修改金额
        if (!ObjectUtils.isEmpty(newMoney)) {
            Payable byId = this.getById(payable.getId());
            Long oldMoney = byId.getMoney();

            //判断修改金额为增加还是减少
            if (newMoney > oldMoney) {
                long updateMoney = newMoney - oldMoney;
                generalLedger.setMoney(generalLedger.getMoney() + updateMoney);
            } else if (newMoney < oldMoney) {
                long updateMoney = oldMoney - newMoney;
                generalLedger.setMoney(generalLedger.getMoney() - updateMoney);
            }
            generalLedgerService.updateById(generalLedger);
        }
        //更新应付账信息
        this.updateById(payable);
        //记录日志
        FinancialJournal financialJournal = new FinancialJournal
                (BaseContext.getCurrentId(), SuperConstant.PayableTable, SuperConstant.Update, payable.getId().toString());
        financialJournalService.save(financialJournal);

        return R.success("更新成功");
    }


}
